//`define AUTO_RESET_PHY // PHY出错时是否复位
//`define ENABLE_RESET_PLL // 是否可通过网络复位PLL

`timescale    1ps/1ps
`default_nettype none

//-----------------------------------
//`define G602
//`define G605
  `define G612
//`define G616
//`define G628
//`define H611
//`define H614
//-----------------------------------

module SA101_G01
    #(
    //程序版本信息
    parameter [31:0] VERSION_DATE     =  32'h19_07_11_18,
    parameter [7:0]  MAIN_FUNCTION    =  "S",
    parameter [7:0]  SUB_FUNCTION     =  "A",
    parameter [7:0]  MAIN_SOLUTION    =  1,
    parameter [7:0]  SUB_SOLUTION     =  2,
    parameter [7:0]  APPLICATION_TYPE =  "G",
    parameter [7:0]  MAIN_VERSION     =  2,
    parameter [7:0]  SUB_VERSION      =  0,
    parameter [7:0]  MINI_VERSION     =  0,

// DW: data width,表示FPGA内部的LED数据宽度
// DP: data pin,  表示LED数据通路占用的FPGA引脚数

`ifdef G602
    parameter   DW  = 64,
    parameter   DP  = 64
`endif

`ifdef G605
    parameter   DW  = 72,
    parameter   DP  = 72
`endif

`ifdef G612
    parameter   DW  = 72,
    parameter   DP  = 72
`endif

`ifdef G616
    parameter   DW  = 96,
    parameter   DP  = 72
`endif

`ifdef G628
    parameter   DW  = 96,
    parameter   DP  = 72
`endif

`ifdef H611
    parameter   DW  = 36,
    parameter   DP  = 36
`endif

`ifdef H614
    parameter   DW  = 72,
    parameter   DP  = 72
`endif
    )
    (
    input  wire        sclkin,
    input  wire        key_in,
    output wire        phy_rst_n,

    output wire        mdc,
    inout  tri         mdio,

    input       wire        JTCK        ,
    input       wire        JTDI        ,
    input       wire        JTMS        ,
    output      wire        JTDO        ,

    input  wire        gp0_rxc,
    input  wire        gp0_rxdv,
    input  wire [3:0]  gp0_rxd,
    output wire        gp0_txc,
    output wire        gp0_txen,
    output wire [3:0]  gp0_txd,

    input  wire        gp1_rxc,
    input  wire        gp1_rxdv,
    input  wire [3:0]  gp1_rxd,
    output wire        gp1_txc,
    output wire        gp1_txen,
    output wire [3:0]  gp1_txd,

    output wire        O_oe_out,
    output wire        O_load_out,
    output wire [4:0]  O_scan_out,
    output wire        O_clock_out,
    output wire [DP-1:0] O_data_out,

    output wire        O_sdram_cs_n,
    output wire        O_sdram_cke,
    output wire [3:0]  O_sdram_dqm,
    output wire        O_sdram_clk,    // CLK
    output wire        O_sdram_ras_n,  // RAS#
    output wire        O_sdram_cas_n,  // CAS#
    output wire        O_sdram_we_n,   // WE#
    output wire [1:0]  O_sdram_ba,     // BA
    output wire [10:0] O_sdram_addr,   // A
    inout  tri  [31:0] IO_sdram_dq,     // DQ output

    inout  tri         flash_SO,
    output wire        flash_SCK,
    inout  tri         flash_SI,
    output wire        flash_CS_n,


`ifdef ALTERA
    output reg         O_frame_sync,
`endif

    output wire        led_g
);


localparam
    START_IDLE  = 2'b00,
    START_DELAY = 2'b01,
    START_OK    = 2'b10;

//****************************************************************
//        内部信号
//****************************************************************
wire        init_pll;
wire        resetb;
wire        clk_125M;
wire        sclk;   
wire        sclk_shift;
wire        clk_mcu;
wire        time_1ms,time_125ms,time_250ms;
wire        time_1ms_sync,time_16us_sync,time_15ms_sync,time_250ms_sync,time_1s_sync;
wire        t_us,t_s;
wire        rec_flag;
wire        rec_error;
wire        rec_error_sync;
wire        send_flag;
wire        pre_flag;
wire [7:0]  rec_data,send_data;
wire [1:0]  rec_vendor;
wire        input_active;
wire        redu_flag;
wire        blank_flag;
wire [1:0]  gp0_rx_type;
wire [1:0]  gp1_rx_type;
wire        fpga_rec_flag;

wire        init_mode;
wire        init_end;
wire        reboot_en;
wire        comm_en;
wire        reconfig_en;
wire        reconfig_adjust_en;
wire        reconfig_pll_en;
wire [1:0]  reboot_sel;

wire        set_d_ok;
wire [15:0] set_addr;

wire [7:0]  set_data;
wire [7:0]  state_data;


wire [23:0] tout;
wire        inner_led_g;
wire        id_is_valid;
wire [63:0] id;
wire        lock_enable;
wire [31:0] lock;
wire        locked;


// 显示设置包内容
wire        disp_set_pkg_received;
wire [7:0]  state;
wire [7:0]  state_2;
wire [7:0]  disp_contrast;
wire [7:0]  disp_light;
// to led_display_top
wire        frame_start;
wire        frame_end;
wire        row_end;
wire        burst_start;
wire [12:0] burst_row;
wire [12:0] burst_col;
wire        pixel_en;
wire [7:0]  pixel_data;
//
wire        read_flash_status_L;
wire [7:0]  flash_status_L_rd;
wire        enable_flash_swp;
wire        disable_flash_swp;
//
reg  [ 2: 0] start_state,next_start_state;
reg  [ 12: 0] delay_cnt;
reg         first_reset;
//
wire        sdram_refresh_en;


wire        gp0_rx_error;
wire        gp1_rx_error;

wire        gp0_rx_dv;
wire        gp1_rx_dv;

wire        pll_lock;

wire        frame_sync;
reg  [ 3: 0]frame_cnt;

wire        packet_load               ;
wire        mcu_rec_end               ;
wire [1:0]  fpga_flag_next            ;

wire phy_rst_mcu;

wire sdram_ready;

wire key_out;
wire [3:0]change_mode;
wire [9:0]ram_waddr_rgb ;
wire [31:0]ram_wdata_rgb ;
wire ram_wr_rgb   ;


wire  [31:0]  ram_data_w ;
wire  [31:0]  ram_data_r ;
wire  [9:0]   ram_addr ;
wire          ram_wren ;

wire  [23:0]  sdram_addr ;
wire          rw ;
wire          req ;
wire          busy ;
wire  [10:0]  rw_len;

wire          kp_busy;


wire  [3:0]   pll_reset_cnt ;

wire    [20:0]  time_us         ;
wire    [20:0]  sync_us         ;

wire [3:0]       apb_sel              ;
wire [31:0]      apb_addr             ;
wire             apb_rw_en            ;
wire [31:0]      apb_wdata            ;
wire [31:0]      apb_rdata0           ;
wire [31:0]      apb_rdata1           ;
wire [31:0]      apb_rdata2           ;
wire [31:0]      apb_rdata3           ;



//******************************************************************/
//               参数定义
//******************************************************************/
//常数定义
localparam SUB    =0;       //分控
localparam ASSIST =1;       //附属设备
//模块参数设置
localparam DEVICE_TYPE = SUB;


sys_other sys_other
(
    .sclkin             (   sclkin  ), //25m
    .resetb             (   resetb  ),
    .sclk               (   sclk    ), //125m
    .sdram_clk          (   O_sdram_clk ), //125M
    .sclk_shift         (   sclk_shift  ),

    .rec_flag           (   rec_flag    ),
    .rec_error_sync     (   rec_error_sync  ),

    .input_active       (   input_active    ),
    .comm_en            (   comm_en         ),

    .reconfig_pll_en    (   reconfig_pll_en ),

    .led_g              (   led_g           ),

    .pll_reset_cnt_sync (   pll_reset_cnt   ),
    .time_us            (   time_us         ),
    .sync_us            (   sync_us         )
    
);

//**************************************************************
//           千兆级联模块
//**************************************************************
phy_interface
#(
    .DEVICE_TYPE(DEVICE_TYPE)
)
phy_interface(
    .resetb                 (   resetb              ),
    .sclk                   (   sclk                ),
    //.sclk_shift           (   sclk_shift          ),
    .sclk_shift             (   sclk                ),

    .tx_err_en              (   1'b0                ),
    .time_1ms               (   time_us[10]         ), //time_1ms
    .time_125ms             (   time_us[17]         ), //time_125ms

    .gp0_rxc                (   gp0_rxc             ),
    .gp0_rxdv               (   gp0_rxdv            ),
    .gp0_rxd                (   gp0_rxd             ),
    .gp0_txc                (   gp0_txc             ),
    .gp0_txen               (   gp0_txen            ),
    .gp0_txd                (   gp0_txd             ),

    .gp1_rxc                (   gp1_rxc             ),
    .gp1_rxdv               (   gp1_rxdv            ),
    .gp1_rxd                (   gp1_rxd             ),
    .gp1_txc                (   gp1_txc             ),
    .gp1_txen               (   gp1_txen            ),
    .gp1_txd                (   gp1_txd             ),

    .rec_flag               (   rec_flag            ),
    .rec_data               (   rec_data            ),
    .rec_error              (   rec_error           ),
    .rec_error_sync         (   rec_error_sync      ),

    .send_flag              (   send_flag           ),
    .pre_flag               (   pre_flag            ),
    .send_data              (   send_data           ),

    .rec_vendor             (   rec_vendor          ),
    .input_active           (   input_active        ),
    .redu_flag              (   redu_flag           ),
    .blank_flag             (   blank_flag          ),
    
    .gp0_rx_type            (   gp0_rx_type         ),
    .gp1_rx_type            (   gp1_rx_type         ),

    .reset_rx_error         (   1'b0                ),
    .gp0_rx_error           (   gp0_rx_error        ),
    .gp1_rx_error           (   gp1_rx_error        ),

    .gp0_rx_dv_out          (   gp0_rx_dv           ),
    .gp1_rx_dv_out          (   gp1_rx_dv           ),

    .frame_sync             (   frame_sync          )

    );

`ifdef ALTERA
always @(posedge sclk or negedge resetb)
   if(!resetb)
       O_frame_sync <= 1'b0;
   else if(frame_sync)
       O_frame_sync <= 1'b1;
   else if(frame_cnt==9)
       O_frame_sync <= 1'b0;

always @(posedge sclk or negedge resetb)
    if(!resetb)
        frame_cnt <= 0;
    else if(O_frame_sync)
        frame_cnt <= frame_cnt + 1'b1;
    else
        frame_cnt <= 0;
`endif

//系统通信
sys_comm#(

    .MAIN_FUNCTION      (MAIN_FUNCTION      ),
    .SUB_FUNCTION       (SUB_FUNCTION       ),
    .MAIN_SOLUTION      (MAIN_SOLUTION      ),
    .SUB_SOLUTION       (SUB_SOLUTION       ),
    .APPLICATION_TYPE   (APPLICATION_TYPE   ),
    .MAIN_VERSION       (MAIN_VERSION       ),
    .SUB_VERSION        (SUB_VERSION        ),
    .MINI_VERSION       (MINI_VERSION       ),
    .VERSION_DATE       (VERSION_DATE       ), 
    
    .DEVICE_TYPE        (DEVICE_TYPE        ),
    .FLASH_BIAS         (24'hB1CE6          )
)sys_comm
(
    .resetb                 (   resetb          ),
    .sclk                   (   sclk            ),
    .sclkin                 (   sclkin          ),

    .JTCK                   (   JTCK            ),
    .JTDI                   (   JTDI            ),
    .JTMS                   (   JTMS            ),
    .JTDO                   (   JTDO            ),

    .flash_SCK              (   flash_SCK       ),
    .flash_CS_n             (   flash_CS_n      ),
    .FLASH_SI               (   flash_SI        ),
    .FLASH_SO               (   flash_SO        ),
    
    .gp0_rx_type            (   gp0_rx_type     ),
    .gp1_rx_type            (   gp1_rx_type     ),
        
    .rec_flag               (   rec_flag        ),
    .rec_error              (   rec_error       ),
    .rec_data               (   rec_data        ),
    .rec_vendor             (   rec_vendor      ),
                                                
    .send_flag              (   send_flag       ),
    .pre_flag               (   pre_flag        ),
    .send_data              (   send_data       ),
                                                
    .blank_flag             (   blank_flag      ),
    .redu_flag              (   redu_flag       ),
    
    .lock_enable            (   lock_enable     ),
    .locked                 (   locked          ),

    .time_1ms_sync          (   sync_us[10]     ),  //time_1ms_sync   
    .time_1s_sync           (   sync_us[20]     ),  //time_1s_sync    
    .time_15ms_sync         (   sync_us[14]     ),  //time_15ms_sync  
    .time_250ms_sync        (   sync_us[18]     ),  //time_250ms_sync 

   /****************phy *******************/
    .phy_rst_mcu            (   phy_rst_n       ),
    .mdc                    (   mdc             ),
    .mdio                   (   mdio            ),
    //sdram
    .sdram_ready            (   sdram_ready     ),
    .sdram_busy             (   busy            ),
    
    .init_mode              (   init_mode       ),
    .comm_en                (   comm_en         ),
    
    .pll_reset_cnt          (   pll_reset_cnt   ),

    .reconfig_pll_en        (   reconfig_pll_en ),
    
     // //内部寄存器设置总线
    
    .apb_sel                ( apb_sel           ),
    .apb_addr               ( apb_addr          ),
    .apb_rw_en              ( apb_rw_en         ),
    .apb_wdata              ( apb_wdata         ),
    .apb_rdata1             ( apb_rdata1        ),
    .apb_rdata2             ( apb_rdata2        ),
    
    .frame_start            (   frame_start     ),
    //按键    
    .key_in                 (   key_in          ),
    //key_patter
    .kp_busy                (   kp_busy         )
      
);

led_display_top  /*{{{*/
    #(
    .DW              (DW              ),
    .DP              (DP              )
    )
  disp(
    .I_sclk             (   sclk                ),
    .I_sdram_clk        (   sclk                ),
    .I_rst_n            (   resetb              ),

 //PHY模块接口
    .mac_flag           (   rec_flag            ),
    .mac_data           (   rec_data            ),
    .mac_error          (   rec_error           ),
    .mac_vendor         (   rec_vendor          ),
    
    .lock_enable        (   lock_enable         ),
    .locked             (   locked              ),
    
    .O_frame_start      (   frame_start         ),

    // //key_patter
    .kp_busy            (   kp_busy             ),
    
    .I_time_1ms_sync    (   sync_us[10]         ),  // time_1ms_sync 
    .I_time_1s_sync     (   sync_us[20]         ),  // time_1s_sync  

    .I_bus_init_done    (   ~init_mode          ),
    .apb_sel            (   apb_sel             ),
    .apb_addr           (   apb_addr            ),
    .apb_rw_en          (   apb_rw_en           ),
    .apb_wdata          (   apb_wdata           ),
    .apb_rdata1         (   apb_rdata1          ),

     // //sdram  ram 缓存
    .busy               (   busy                ),     //忙状态
    
    .I_self_sync        (   frame_sync          ),

    .O_oe_out           (   O_oe_out            ),
    .O_load_out         (   O_load_out          ),
  //.O_deghost_ctrl     (   O_deghost_ctrl      ),
    .O_scan_out         (   O_scan_out          ),
    .O_clock_out        (   O_clock_out         ),
    .O_data_out         (   O_data_out          ),
    .O_sdram_ready      (   sdram_ready         ),
    .O_sdram_cke        (                       ),
    .O_sdram_cs_n       (                       ),
    .O_sdram_ras_n      (   O_sdram_ras_n       ),
    .O_sdram_cas_n      (   O_sdram_cas_n       ),
    .O_sdram_we_n       (   O_sdram_we_n        ),
    .O_sdram_ba         (   O_sdram_ba          ),
    .O_sdram_addr       (   O_sdram_addr        ),
    .O_sdram_dqm        (   O_sdram_dqm         ),
    .IO_sdram_dq        (   IO_sdram_dq         )
);/*}}}*/

assign O_sdram_cs_n = 1'b0;
assign O_sdram_cke = 1'b1;
// assign O_sdram_dqm = 1'b0;

endmodule

`default_nettype wire

